package com.example.onlinemusic.service.impl;

import com.example.onlinemusic.mapper.MusicMapper;
import com.example.onlinemusic.model.Music;
import com.example.onlinemusic.model.User;
import com.example.onlinemusic.service.LoveMusicService;
import com.example.onlinemusic.service.MusicService;
import com.example.onlinemusic.tools.Constant;
import com.example.onlinemusic.tools.ResponseBodyMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpSession;
import javax.websocket.Session;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Date;
import java.util.List;

@Service
public class MusicServiceImpl implements MusicService {

    @Value("${music.local.path}")
    private String MUSIC_PATH; // 保存音乐的路径

    @Autowired
    private MusicMapper musicMapper;

    @Autowired
    private LoveMusicService loveMusicService;

    /**
     * 验证MP3代码说明：
     * 通过验证文件的二进制头部信息来判断是否为 MP3 文件
     * 1.验证原理：
     *      检查文件开头是否包含ID3标签（ID3v2 标签特征）
     *      检查是否包含 MP3 帧同步信息（第一字节为0xFF，第二字节高 3 位为111）
     * 2.核心方法：
     *      isMp3File()方法通过读取文件前 10 个字节进行格式验证
     *      使用 try-with-resources 确保输入流正确关闭
     *      两种验证方式只要有一种通过就判定为 MP3 文件
     * 这种验证方式比单纯检查文件后缀名更可靠，因为后缀名可以被轻易修改，而文件的二进制头部信息更能准确反映文件真实格式。
     */

    // MP3文件的特征字节（ID3v2标签头或帧同步信息）
    private static final byte[] ID3_HEADER = {'I', 'D', '3'};
    private static final byte FRAME_SYNC_FIRST = (byte) 0xFF;
    private static final int FRAME_SYNC_SECOND_MASK = 0xE0; // 11100000




    /**
     * 将音乐路径插入到数据库中；音乐上传到服务器
     * @param singer
     * @param file
     * @param session
     * @return
     */
    @Override
    public int insertMusic(String singer, MultipartFile file, HttpSession session) {

        // 验证文件是否为MP3
        if (!isMp3File(file)) {
            return -1;
        }

        // 上传音乐逻辑
        String filenameAndType = file.getOriginalFilename(); // 音乐的全名包括后缀MP3
        String path = MUSIC_PATH + "/" + filenameAndType; // 此音乐的完整路径

        File dest = new File(path); // 将当前音乐路径变为可操作的java对象
        File parentFile = dest.getParentFile(); // 音乐的父目录
        // 如果音乐的父目录不存在，则创建
        if (parentFile != null && !parentFile.exists()) {
            parentFile.mkdirs();
        }

        try {
            // 插入到数据库中
            String title = filenameAndType.substring(0,filenameAndType.lastIndexOf("."));// 截取后缀前的字符
            User user = (User)session.getAttribute(Constant.USERINFO_SESSION_KEY); // 当前登录用户的id
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            String time = sdf.format(new Date());
            //这⾥会被⽤到 播放⾳乐的模块，不存入后缀，因为所有音乐的后缀都相同，取出来的时候在前端加后缀即可
            String url = "/music/get?musicName="+title;
            int insert = musicMapper.insertMusic(title, singer, time, url, user.getId());

            if (insert > 0) {
                file.transferTo(dest); // 如果数据库插入成功，将上传的文件保存到目标路径（上传到服务器）
                return 1;
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
        return -1;
    }


    /**
     * 判断文件是否为MP3格式
     */
    private boolean isMp3File(MultipartFile file) {
        try (InputStream is = file.getInputStream()) {
            // 读取文件前10个字节用于验证
            byte[] header = new byte[10];
            int read = is.read(header);

            // 验证ID3v2标签头（文件开头为"ID3"）
            if (read >= 3) {
                boolean isId3 = true;
                for (int i = 0; i < 3; i++) {
                    if (header[i] != ID3_HEADER[i]) {
                        isId3 = false;
                        break;
                    }
                }
                if (isId3) {
                    return true;
                }
            }

            // 验证MP3帧同步信息（FF + E0以上）
            if (read >= 2) {
                if (header[0] == FRAME_SYNC_FIRST &&
                        (header[1] & FRAME_SYNC_SECOND_MASK) == FRAME_SYNC_SECOND_MASK) {
                    //  header[1] & FRAME_SYNC_SECOND_MASK 运算，可提取高3位，如果结果等于 0xE0，说明高 3 位是 111，符合帧同步规则
                    return true;
                }
            }

            // 两种验证都不通过则不是MP3
            return false;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 通过歌名和作者来查询音乐
     * @param title
     * @param singer
     * @return
     */
    @Override
    public Music selectByTitleAndSinger(String title, String singer) {
        return musicMapper.selectTitleAndSinger(title, singer);
    }


    /**
     * 通过musicId来删除音乐，删除音乐包括1.删除数据库，2.本地服务器中的音乐文件 3.如果收藏中收藏了这首音乐则也要删除
     * @param musicId
     * @return
     */
    @Override
    public int deleteMusicById(int musicId) {
        // 先删除本地服务器中的音乐文件
        Music music = musicMapper.selectByMusicId(musicId);
        // 如果当前音乐不存在
        if (music == null) {
            return -1;
        }
        String title = music.getTitle();
        File file = new File(MUSIC_PATH + "/" + title + ".mp3");
        boolean delete = file.delete(); // 删除文件
        if (!delete) {
            return -1;
        }

        // 再删除数据库中的记录
        int deleteResult = musicMapper.deleteMusicById(musicId);
        System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~deleteResult:"+deleteResult);
        if (deleteResult > 0) {
            // 查看收藏中有没有该音乐，如果有则删除
            Boolean flag = loveMusicService.findLoveMusicByMusicId(musicId);
            if (flag) {
                loveMusicService.cancelLoveMusicByMusicId(musicId);
            }
            return 1;
        } else {
            return -1;
        }
    }

    /**
     * 批量删除音乐  删除音乐包括1.删除数据库，2.本地服务器中的音乐文件 3.如果收藏中收藏了这首音乐则也要删除
     * @param musicIds
     * @return
     */
    @Override
    public int deleteSelMusicById(List<Integer> musicIds) {
        for (Integer musicId : musicIds) {
            int i = deleteMusicById(musicId);
            // 有音乐删除失败
            if (i < 0) {
               return -1;
            }
            // 查看收藏中有没有该音乐，如果有则删除
            Boolean flag = loveMusicService.findLoveMusicByMusicId(musicId);
            if (flag) {
                loveMusicService.cancelLoveMusicByMusicId(musicId);
            }
        }
        // 全部删除成功
        return 1;
    }

    /**
     * 查询所有音乐，当输入框输入为空时
     * @return
     */
    @Override
    public List<Music> findAllMusic() {
        return musicMapper.findAllMusic();
    }

    /**
     * 查询音乐名匹配的音乐
     * @param title
     * @return
     */
    @Override
    public List<Music> findMusicByName(String title) {
        return musicMapper.findMusicByName(title);
    }



}
